package com.itheima.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Snowflake;
import com.alibaba.fastjson.JSON;
import com.itheima.common.R;
import com.itheima.common.TokenHolder;
import com.itheima.constant.TokenConstant;
import com.itheima.domain.Employee;
import com.itheima.dto.EmpAddDto;
import com.itheima.service.EmployeeService;
import com.itheima.vo.EmpPageVo;
import com.itheima.vo.EmpTokenVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author CSY
 * 2022/5/7    21:00
 */
@RestController
@Slf4j
@RequestMapping("/employee")
public class EmployeeController {

    @Autowired
    private EmployeeService employeeService;
    @Autowired
    private RedisTemplate redisTemplate;

    @PostMapping("/login")
    public R<EmpTokenVo> login(@RequestBody Employee employee){

        //步骤一：获取用户输入的密码password
        String password = employee.getPassword();


        password = DigestUtils.md5DigestAsHex(password.getBytes());

        String username = employee.getUsername();

        // 步骤三：到数据库中查找相应用户名和密码的员工记录
        Employee emp = employeeService.selectByUP(username,password);

        // 步骤四：如果没有查询到则返回登录失败结果
        if (Objects.isNull(emp)) {
            return R.error("用户名或密码错误");
        }

        // 步骤五：生成token，Token为当前登录用户的身份凭证，后续前端每次请求其他接口时，需要带上token证明已完成登录
        // Token需要具备两个条件
        // 1. 不能重复
        // 2. 通过token，可以找到用户的身份信息
        // 3. 需要加密
        // 所以这里用 MD5(时间戳 + 当前用户id) 的方式生成
        long tokenString = System.currentTimeMillis() + emp.getId();
        String token = DigestUtils.md5DigestAsHex(String.valueOf(tokenString).getBytes());

        // 步骤六：将token记录到redis
        // token做key，值为对应的用户信息
        redisTemplate.opsForValue().set(TokenConstant.EMPLOYEE_TOKEN_PREFIX + token, JSON.toJSONString(emp), 48L, TimeUnit.HOURS);

        EmpTokenVo tokenVo = new EmpTokenVo();
        BeanUtils.copyProperties(emp, tokenVo);
        tokenVo.setToken(token);

        // 步骤七：登录成功，将员工id存入Session并返回登录成功结果
        return R.success(tokenVo);
    }

    @GetMapping("/page")
    public R<EmpPageVo> selectPage(@RequestParam("page") int page,
                                   @RequestParam("pageSize") int pageSize, String name){


        List<Employee> employees = employeeService.selectPage(page, pageSize, name);
        int count = employeeService.selectCount(name);
        EmpPageVo empVo = new EmpPageVo();
        empVo.setTotal(count);
        empVo.setRecords(employees);
        empVo.setSize(pageSize);
        empVo.setCurrent(page);

        return R.success(empVo);

    }

    /**
     * 登出
     * @param httpServletRequest
     * @return
     */
    @PostMapping("/logout")
    public R<String> logout(HttpServletRequest httpServletRequest){
        String token = httpServletRequest.getHeader("Authorization");

        redisTemplate.delete(TokenConstant.EMPLOYEE_TOKEN_PREFIX +token);

        return R.success("退出成功");
    }

    /**
     * 新增员工的方法
     * @param empAddDto
     * @return
     */
    @PostMapping
    public R<String> add(@RequestBody EmpAddDto empAddDto){

        //获取登录的id值
        String empId = TokenHolder.getCurrentId();

        //添加者
        empAddDto.setCreateUser(Long.valueOf(empId));
        String empA = new Snowflake().nextIdStr();
        //id
        empAddDto.setId(Long.valueOf(empA));
        String s = DigestUtils.md5DigestAsHex("123456".getBytes(StandardCharsets.UTF_8));
        //密码
        empAddDto.setPassword(s);
        //修改者
        empAddDto.setUpdateUser(Long.valueOf(empId));
        //状态初始为1
        empAddDto.setStatus(1);
        //创建时间
        empAddDto.setCreateTime(LocalDateTime.now());
        //修改时间
       empAddDto.setUpdateTime(LocalDateTime.now());


        boolean b = employeeService.insert(empAddDto);

        return b? R.success("添加成功"): R.error("添加失败");
    }

    /**
     *      修改员工信息
     * @param employee
     * @return
     */
    @PutMapping
    public R<String> updateByStatus(@RequestBody Employee employee){


        //修改时间
        employee.setUpdateTime(LocalDateTime.now());

        //修改
        boolean b = employeeService.update(employee);


        return b?R.success("修改成功"):R.error("修改失败");
    }

    /**
     * 返回员工信息
     * @param id
     * @return
     */
    @GetMapping("{id}")
    public R<Employee> updateById(@PathVariable  String id){

        Employee employee = employeeService.selectById(id);

        return employee!=null? R.success(employee):R.error("数据异常");

    }




}
